package com.ruoyi.iot.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.iot.domain.*;
import com.ruoyi.iot.domain.dto.ProjectDTO;
import com.ruoyi.iot.domain.vo.plus.IotProjectPlus;
import com.ruoyi.iot.domain.vo.ProjectVO;
import com.ruoyi.iot.domain.vo.enums.ENetworkState;
import com.ruoyi.iot.domain.vo.enums.EProtocol;
import com.ruoyi.iot.domain.vo.exchange.IotWrapperDTO;
import com.ruoyi.iot.exchange.IotExchangeServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.iot.service.IIotProjectService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.page.TableDataInfo;

/**
 * 项目Controller
 *
 * @author ruoyi
 * @date 2022-12-27
 */
@RestController
@RequestMapping("/project")
@Slf4j
public class IotProjectController extends BaseController
{
    /**
     * 项目服务
     */
    @Autowired
    private IIotProjectService iotProjectService;



    /**
     * 交换机服务
     */
    @Autowired
    private IotExchangeServiceImpl iotExchangeServiceImpl;




    /**
     * 查询项目列表
     */
    @RequiresPermissions("iot:project:list")
    @GetMapping("/list")
    public TableDataInfo list(IotProject iotProject)
    {
        startPage();
        log.info("query:" + JSON.toJSONString(iotProject));
        List<IotProject> list = iotProjectService.selectIotProjectList(iotProject);
        List<IotProjectPlus> iotProjectPluses = new ArrayList<>();
        for (IotProject item : list) {
            IotProjectPlus iotProjectPlus = new IotProjectPlus();
            BeanUtils.copyProperties(item, iotProjectPlus);
            log.info("item:" + JSON.toJSONString(item));
            if(item.getNetworkState() == null) {
                iotProjectPlus.setNextAction("未知");
                continue;
            } else {
            ENetworkState eNetworkState = ENetworkState.getType(item.getNetworkState().intValue());
            log.info("projectState:" + eNetworkState.toString());
            switch (eNetworkState){
                case prepare:{
                    iotProjectPlus.setNextAction("运行");
                }
                break;
                case run: {
                    iotProjectPlus.setNextAction("停止");
                }
                break;
                case stop:{
                    iotProjectPlus.setNextAction("就绪");
                }
                break;
                case unknow:{
                    iotProjectPlus.setNextAction("未知");
                }
                break;
            } }
            iotProjectPluses.add(iotProjectPlus);
        }
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setRows(iotProjectPluses);
        rspData.setMsg("查询成功");
        rspData.setTotal(new PageInfo(list).getTotal());

        return  rspData;
    }

    /**
     * 导出项目列表
     */
    @RequiresPermissions("iot:project:export")
    @Log(title = "项目", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, IotProject iotProject)
    {
        List<IotProject> list = iotProjectService.selectIotProjectList(iotProject);
        ExcelUtil<IotProject> util = new ExcelUtil<IotProject>(IotProject.class);
        util.exportExcel(response, list, "项目数据");
    }

    /**
     * 获取项目详细信息
     */
    @RequiresPermissions("iot:project:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(iotProjectService.selectIotProjectById(id));
    }

    /**
     * 新增项目
     */
    @RequiresPermissions("iot:project:add")
    @Log(title = "项目", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody IotProject iotProject)
    {
        return toAjax(iotProjectService.insertIotProject(iotProject));
    }

    /**
     * 存项目信息
     * @param projectDTO 项目数据
     * @return
     */
    @PostMapping("/new")
    public IotWrapperDTO<Boolean> saveProject(@RequestBody ProjectDTO projectDTO)
    {
        log.info("new project:" + JSON.toJSONString(projectDTO));
        IotProject iotProject = new IotProject();
        BeanUtils.copyProperties(projectDTO,iotProject);
        //项目设置状态，设置启动时间
        iotProject.setState(1L);
        iotProject.setStartupTime(new Date());
        Boolean rst = iotProjectService.insertIotProject(iotProject) > 0;
        IotWrapperDTO<Boolean> iotWrapperDTO = new IotWrapperDTO<>();
        iotWrapperDTO.setData(rst);

        return iotWrapperDTO;
    }




    /**
     * 修改项目
     */
    @RequiresPermissions("iot:project:edit")
    @Log(title = "项目", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody IotProject iotProject)
    {
        return toAjax(iotProjectService.updateIotProject(iotProject));
    }

    /**
     * 删除项目
     */
    @RequiresPermissions("iot:project:remove")
    @Log(title = "项目", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(iotProjectService.deleteIotProjectByIds(ids));
    }


    /**
     * 开始执行
     * @param iotProjectPlus
     * @return
     */
    @PostMapping("startOver")
    public AjaxResult startProjectServer(@RequestBody IotProjectPlus iotProjectPlus) {

        Long projectId = iotProjectPlus.getId();
        executeNext(projectId);
        IotProject iotProject = iotProjectService.selectIotProjectById(iotProjectPlus.getId());
        BeanUtils.copyProperties(iotProject, iotProjectPlus);
        ENetworkState eNetworkState = ENetworkState.getType(iotProject.getState().intValue());
        switch (eNetworkState){
            case prepare:{
                iotProjectPlus.setNextAction("运行");
            }
            break;
            case run: {
                iotProjectPlus.setNextAction("停止");
            }
            break;
            case stop:{
                iotProjectPlus.setNextAction("就绪");
            }
            break;
        }
        log.info("update project:" + JSON.toJSONString(iotProjectPlus) );
        return AjaxResult.success(iotProjectPlus);
    }

    /**
     * 执行下一步
     * @param projectId 项目id
     */
    private void executeNext(Long projectId) {
        IotProject iotProject = iotProjectService.selectIotProjectById(projectId);
        Integer protocol =  iotProject.getNetworkProtocol().intValue();
        EProtocol eProtocol = EProtocol.getType(protocol);

        if (eProtocol == EProtocol.TCP) {
            ENetworkState productState = ENetworkState.getType(iotProject.getNetworkState().intValue());
            switch (productState){
                case prepare:{
                    iotProjectService.startUpProjectServer(iotProject);
                }
                break;
                case run: {
                    ProjectVO projectVO = new ProjectVO();
                    projectVO.setProjectId(projectId);
                    projectVO.setProjectName(iotProject.getName());
                    iotProject.setNetworkState(ENetworkState.stop.getValue().longValue());
                    log.info(String.format("stop product %s  port:%s",iotProject.getName(),iotProject.getNetworkPort()));
                    iotExchangeServiceImpl.stopProjectServer(projectVO);
                    iotProjectService.updateIotProject(iotProject);

                }
                break;
                case stop:{
                    iotProject.setNetworkState(ENetworkState.prepare.getValue().longValue());
                    log.info(String.format("prepare product %s  port:%s",iotProject.getName(),iotProject.getNetworkPort()));
                    iotProjectService.updateIotProject(iotProject);
                }
                break;
            }
        }
    }





    /**
     * 扫描数据库，启动运行状态产品
     */
    @PostConstruct
    public void scanDBStartUpProduct() {

        IotProject iotProject = new IotProject();
        iotProject.setNetworkState(ENetworkState.run.getValue().longValue());
        List<IotProject> iotProjectList = iotProjectService.selectIotProjectList(iotProject);

        log.info("size:" + iotProjectList.size());

        for(IotProject item : iotProjectList) {
            //启动产品服务
           iotProjectService.startUpProjectServer(item);
        }

    }








}
